import java.io.DataInputStream;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Date;

import org.xml.sax.SAXException;

import com.keithpower.gekmlib.Folder;
import com.keithpower.gekmlib.KMLParser;
import com.keithpower.gekmlib.Kml;
import com.keithpower.gekmlib.Placemark;
import com.keithpower.gekmlib.Point;
import com.keithpower.gekmlib.TimeStamp;

public class TCPDesktopServer implements Runnable{
	
    public static final String SERVERIP = "127.0.0.1";
    public static final int SERVERPORT = 5432;
    private Kml _kml;
    private boolean _isgenerated = false;
         
    public void run() 
    {
         try 
         {
        	 if(!_isgenerated)
        	 {
        		 checkExistingKmlFile();
        	 }
        	 Report test = new Report(new Coordinate(56.144,10.199,0), new Date().getTime(),"ServerStart","Rapport");
        	 addCoordinate(test);
        	 System.out.println("S: Connecting...");
              
             ServerSocket serverSocket = new ServerSocket(SERVERPORT);
             while (true) {
            	  
            	  Socket client = serverSocket.accept();
            	  System.out.println("S: Receiving...");
            	  
            	  try {
            		  
            		  //DataInputStream dis = new DataInputStream(client.getInputStream());
            		  //DataInputStream br = new DataInputStream(client.getInputStream());
            		  Report report = readReport(client);
            		  //System.out.println("S: Received double: " + dis.readDouble() );
            		  System.out.println("S: Received report: \n" + report );
            		  addCoordinate(report);
            		  
                    } catch(Exception e) {
                        System.out.println("S: Error");
                        e.printStackTrace();
                    } finally {
                    	client.close();
                        System.out.println("S: Done.");
                    }
             }
         } 
         catch (Exception e) 
         {
             System.out.println("S: Error");
             e.printStackTrace();
         }
    }
    public void addCoordinate(Report theReport) throws IOException
    {
    	Folder folders[] = _kml.getFolder().getFolders();
    	Boolean foundFolder = false;
    	for(int i = 0; i < folders.length; i++)
    	{
    		System.out.println(folders[i].getName());
    		if(folders[i].getName().equals(theReport.strategyName))
    		{
    			foundFolder = true;
    		}
    	}
    	//create a folder if none was found
    	if(!foundFolder)
    	{
    		Folder newFolder = new Folder();
    		newFolder.setName(theReport.strategyName);
    		_kml.getFolder().addFolder(newFolder);
    	}
    	//reassign the folder list
    	folders = _kml.getFolder().getFolders();
    	for(int i = 0; i < folders.length; i++)
    	{
    		if(folders[i].getName().equals(theReport.strategyName))
    		{
    			Point p = new Point();
    			p.setCoordinates(theReport.position.x + ", " + theReport.position.y);
    			
    			Placemark mark = new Placemark();
    			mark.addPoint(p);
    			TimeStamp t = new TimeStamp();
    			t.setWhen(new Date(theReport.time).toString());
    			mark.addTimeStamp(t);
    			folders[i].addPlacemark(mark);
    		}
    	}
    	//write result to kml
    	File kmlFile = new File("HelloKml.kml");
        FileWriter kmlwriter = new FileWriter(kmlFile);
        String str = _kml.toKML();
        kmlwriter.write(str.toString()+"\n\n");
        kmlwriter.close();
        System.out.println("kml file written");
    	
    }
    
    public void addFirstCoordinate(Report theReport) throws IOException
    {
    	// Start with a blank Kml object, give it a URL
        Kml doc = new Kml();
        doc.setHref("http://localhost/random");

    	// create and add root folder
        Folder root = new Folder();
        root.setName("Root Folder");
        root.setDescription("This is the root folder");
        doc.addFolder(root);

        // create and add another folder to root
        Folder container = new Folder();
        container.setName(theReport.strategyName);
        container.setDescription(theReport.strategyName);
        root.addFolder(container);

        // create and add a Placemark containing a Point
    	Placemark p = new Placemark();
    	Point point1 = new Point();
        point1.setCoordinates(theReport.position.x + ", " + theReport.position.y); // NA will go to 0.0
        p.addPoint(point1);
        container.addPlacemark(p);
        //kml = Kml.unmarshal(new File("HelloKml.kml"));
        File kmlFile = new File("HelloKml.kml");
        FileWriter kmlwriter = new FileWriter(kmlFile);
        String str = doc.toKML();
        //String str = doc.toKML();
        kmlwriter.write(str.toString()+"\n\n");
        kmlwriter.close();
        System.out.println("kml file written");
    }
    
    private void checkExistingKmlFile() throws SAXException, IOException
    {
    	File f = new File("HelloKml.kml");
    	if(f.exists())
    	{
			_kml = new KMLParser().parse(f);
    	}
    	_isgenerated = true;
    }
    
    @SuppressWarnings("deprecation")
	private Report readReport(Socket client) throws IOException
    {
    	DataInputStream dis = new DataInputStream(client.getInputStream());
    	//BufferedReader br = new BufferedReader(new InputStreamReader(is));
    	Coordinate coor = new Coordinate();
    	coor.x = dis.readDouble();
    	coor.y = dis.readDouble();
    	coor.z = dis.readDouble();
    	Date date = new Date(dis.readLong()); //.readLong(report.time);
    	String strategyName = dis.readLine();
    	String configValue = dis.readLine();
    	//dis.close();
    	return new Report(coor, date.getTime(), strategyName, configValue);
    }
    
    public static void main (String a[]) {
    	Thread desktopServerThread = new Thread(new TCPDesktopServer());
    	desktopServerThread.start();
    }
}